#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "queue.h"

// 创建队列
Queue *queueCreate(int capacity) {
    Queue *queue = (Queue *)malloc(sizeof(Queue));
    if (!queue) {
        return NULL;
    }

    queue->front = NULL;
    queue->rear = NULL;
    queue->size = 0;
    queue->capacity = capacity;
    
    pthread_mutex_init(&queue->mutex, NULL);
    pthread_cond_init(&queue->not_empty, NULL);
    pthread_cond_init(&queue->not_full, NULL);

    return queue;
}

// 销毁队列
void queueDestroy(Queue *queue) {
    if (!queue) {
        return;
    }

    pthread_mutex_lock(&queue->mutex);
    
    QueueNode *node = queue->front;
    while (node) {
        QueueNode *next = node->next;
        free(node->data);
        free(node);
        node = next;
    }
    
    pthread_mutex_unlock(&queue->mutex);
    
    pthread_mutex_destroy(&queue->mutex);
    pthread_cond_destroy(&queue->not_empty);
    pthread_cond_destroy(&queue->not_full);
    
    free(queue);
}

// 入队
int queueEnqueue(Queue *queue, void *data, size_t dataSize) {
    if (!queue) {
        return -1;
    }

    pthread_mutex_lock(&queue->mutex);

    // 如果队列已满，等待
    while (queue->capacity > 0 && queue->size >= queue->capacity) {
        pthread_cond_wait(&queue->not_full, &queue->mutex);
    }

    // 创建新节点
    QueueNode *node = (QueueNode *)malloc(sizeof(QueueNode));
    if (!node) {
        pthread_mutex_unlock(&queue->mutex);
        return -1;
    }

    // 复制数据
    node->data = malloc(dataSize);
    if (!node->data) {
        free(node);
        pthread_mutex_unlock(&queue->mutex);
        return -1;
    }
    memcpy(node->data, data, dataSize);
    node->next = NULL;

    // 添加到队列尾部
    if (queue->rear) {
        queue->rear->next = node;
    } else {
        queue->front = node;
    }
    queue->rear = node;
    queue->size++;

    // 通知等待的消费者
    pthread_cond_signal(&queue->not_empty);
    pthread_mutex_unlock(&queue->mutex);

    return 0;
}

// 出队
void *queueDequeue(Queue *queue, size_t *dataSize) {
    (void)dataSize;  // 标记参数未使用
    if (!queue) {
        return NULL;
    }

    pthread_mutex_lock(&queue->mutex);

    // 如果队列为空，等待
    while (queue->size == 0) {
        pthread_cond_wait(&queue->not_empty, &queue->mutex);
    }

    // 获取队首节点
    QueueNode *node = queue->front;
    void *data = node->data;
    
    // 更新队列
    queue->front = node->next;
    if (!queue->front) {
        queue->rear = NULL;
    }
    queue->size--;

    // 通知等待的生产者
    pthread_cond_signal(&queue->not_full);
    pthread_mutex_unlock(&queue->mutex);

    // 释放节点，返回数据
    free(node);
    return data;
}

// 尝试出队（非阻塞）
void *queueTryDequeue(Queue *queue, size_t *dataSize) {
    (void)dataSize;  // 标记参数未使用
    if (!queue) {
        return NULL;
    }

    pthread_mutex_lock(&queue->mutex);

    if (queue->size == 0) {
        pthread_mutex_unlock(&queue->mutex);
        return NULL;
    }

    // 获取队首节点
    QueueNode *node = queue->front;
    void *data = node->data;
    
    // 更新队列
    queue->front = node->next;
    if (!queue->front) {
        queue->rear = NULL;
    }
    queue->size--;

    // 通知等待的生产者
    pthread_cond_signal(&queue->not_full);
    pthread_mutex_unlock(&queue->mutex);

    // 释放节点，返回数据
    free(node);
    return data;
}

// 获取队列大小
int queueSize(Queue *queue) {
    if (!queue) {
        return -1;
    }

    int size;
    pthread_mutex_lock(&queue->mutex);
    size = queue->size;
    pthread_mutex_unlock(&queue->mutex);

    return size;
}

// 清空队列
void queueClear(Queue *queue) {
    if (!queue) {
        return;
    }

    pthread_mutex_lock(&queue->mutex);
    
    QueueNode *node = queue->front;
    while (node) {
        QueueNode *next = node->next;
        free(node->data);
        free(node);
        node = next;
    }
    
    queue->front = NULL;
    queue->rear = NULL;
    queue->size = 0;
    
    // 通知所有等待的生产者
    pthread_cond_broadcast(&queue->not_full);
    pthread_mutex_unlock(&queue->mutex);
}